package wysiwyg.objectHandles
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	
	import mx.binding.utils.BindingUtils;
	import mx.containers.HBox;
	import mx.core.UIComponent;
	
	import wysiwyg.model.Model;
	import wysiwyg.model.ModelLocator;
	import wysiwyg.shapes.ShapeBase;
	
	public class RectangleHandles extends HandleBase
	{
		private var mouseDownPosition:Point;
		public var topLeftHandle:Sprite;
		public var topHandle:Sprite;
		public var topRightHandle:Sprite;
		public var rightHandle:Sprite;
		public var bottomRightHandle:Sprite;
		public var bottomHandle:Sprite;
		public var bottomLeftHandle:Sprite;
		public var leftHandle:Sprite;
		public var transformPoint:Sprite;
		
		public var rotateHandle:Sprite;
		
		public var selectedHandle:Sprite;
		public var switchViewControls:HBox;
		
		private var isTransformPointLocked:Boolean=true;
		
		private var theModel:Model=ModelLocator.getInstance().theModel;
		
		public function RectangleHandles()
		{
			super();
		}
		
		override protected function createChildren():void
		{
			topLeftHandle=createHandle();
			addChild(topLeftHandle);
			
			topHandle=createHandle();
			addChild(topHandle);
			
			topRightHandle=createHandle();
			addChild(topRightHandle);
			
			rightHandle=createHandle();
			addChild(rightHandle);
			
			bottomRightHandle=createHandle();
			addChild(bottomRightHandle);
			
			bottomHandle=createHandle();
			addChild(bottomHandle);
			
			bottomLeftHandle=createHandle();
			addChild(bottomLeftHandle);
			
			leftHandle=createHandle();
			addChild(leftHandle);
			
			rotateHandle=createHandle();
			addChild(rotateHandle);
			
			transformPoint=createHandle();
			addChild(transformPoint);
			
			switchViewControls=new HBox();
			switchViewControls.width=100;
			switchViewControls.height=20;
			switchViewControls.setStyle("horizontalAlign","right");
			switchViewControls.setStyle("styleName","optionButton");
			addChild(switchViewControls);
			BindingUtils.bindSetter(adjustExtraControls,this,"xToUse");
			BindingUtils.bindSetter(adjustExtraControls,this,"yToUse");
			BindingUtils.bindSetter(adjustExtraControls,this,"width");
			BindingUtils.bindSetter(adjustExtraControls,this,"height");
		}
		private function adjustExtraControls(value:Number):void
		{
			switchViewControls.x=xToUse+width-switchViewControls.width;
			switchViewControls.y=yToUse-switchViewControls.height;
		}
		private function createHandle():Sprite
		{
			var sprite:Sprite=new Sprite();
			sprite.graphics.beginFill(0xFF0000,.4);
			sprite.graphics.drawCircle(0,0,5);
			sprite.graphics.endFill();
			sprite.addEventListener(MouseEvent.MOUSE_DOWN,handleDown);
			return sprite;
		}
		
		private function handleDown(event:MouseEvent):void
		{
			stage.addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
			stage.addEventListener(MouseEvent.MOUSE_UP,handleMouseUp);
			selectedHandle=event.target as Sprite;
			mouseDownPosition=new Point();	
			mouseDownPosition.x=theModel.workspace.mouseX;
			mouseDownPosition.y=theModel.workspace.mouseY;
		}
		private function handleMouseUp(event:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE,handleMouseMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP,handleMouseUp);
			handleMouseMove(event);
			selectedHandle=null;	
		}
		override public function positionToCurrentShape():void
		{
			topLeftHandle.x=xToUse;
			topLeftHandle.y=yToUse;
			
			topHandle.x=xToUse+width/2;
			topHandle.y=yToUse;
			
			topRightHandle.x=xToUse+width;
			topRightHandle.y=yToUse;
			
			rightHandle.x=xToUse+width;
			rightHandle.y=yToUse+height/2;
			
			bottomRightHandle.x=xToUse+width;
			bottomRightHandle.y=yToUse+height;
			
			bottomHandle.x=xToUse+width/2;
			bottomHandle.y=yToUse+height;
			
			bottomLeftHandle.x=xToUse;
			bottomLeftHandle.y=yToUse+height;
			
			leftHandle.x=xToUse;
			leftHandle.y=yToUse+height/2;
			
			rotateHandle.x=xToUse+width+20;
			rotateHandle.y=yToUse+height/2;
			
			if(isTransformPointLocked)
			{
				transformPoint.x=xToUse+width/2;
				transformPoint.y=yToUse+height/2;
			}
			
			if(!isNaN(rotationToUse))
			{
				var transMatrix:Matrix=new Matrix();
				transMatrix.tx-=transformPoint.x;
				transMatrix.ty-=transformPoint.y;
				transMatrix.rotate(rotationToUse*Math.PI/180);
				transMatrix.tx+=transformPoint.x;
				transMatrix.ty+=transformPoint.y;
				
				transform.matrix=transMatrix;
			}
		}
		private function handleMouseMove(event:MouseEvent):void
		{
			if(!selectedHandle)
				return;
			//For each handle follow this pattern
			//1. update the handle position itself
			//2. update the bottomRight and topLeft handles since these will in the end determine the position and size of the shape
			//3. *update the width height and position and then update the other handles based on the new position and dimensions (*after all handle conditionals)
			if(selectedHandle==topLeftHandle)
			{
				topLeftHandle.x=theModel.workspace.mouseX;
				topLeftHandle.y=theModel.workspace.mouseY;
			}
			if(selectedHandle==topHandle)
			{
				topHandle.y=theModel.workspace.mouseY;
				topLeftHandle.y=topHandle.y;
			}
			if(selectedHandle==topRightHandle)
			{
				topRightHandle.x=theModel.workspace.mouseX;
				topRightHandle.y=theModel.workspace.mouseY;
				
				bottomRightHandle.x=topRightHandle.x;
				topLeftHandle.y=topRightHandle.y;
			}
			if(selectedHandle==rightHandle)
			{
				rightHandle.x=theModel.workspace.mouseX;
				bottomRightHandle.x=rightHandle.x;
			}
			if(selectedHandle==bottomRightHandle)
			{
				bottomRightHandle.x=theModel.workspace.mouseX;
				bottomRightHandle.y=theModel.workspace.mouseY;
			}
			if(selectedHandle==bottomHandle)
			{
				bottomHandle.y=theModel.workspace.mouseY;
				bottomRightHandle.y=bottomHandle.y;
			}
			if(selectedHandle==bottomLeftHandle)
			{
				bottomLeftHandle.x=theModel.workspace.mouseX;
				bottomLeftHandle.y=theModel.workspace.mouseY;
				
				bottomRightHandle.y=bottomLeftHandle.y;
				topLeftHandle.x=bottomLeftHandle.x;
			}
			if(selectedHandle==leftHandle)
			{
				leftHandle.x=theModel.workspace.mouseX;
				topLeftHandle.x=leftHandle.x;
			}
			if(selectedHandle==transformPoint)
			{
				transformPoint.x=theModel.workspace.mouseX;
				transformPoint.y=theModel.workspace.mouseY;
				isTransformPointLocked=false;
			}
		
			//If the X position changed
			if(xToUse!=topLeftHandle.x)
			{
				xToUse=topLeftHandle.x;
				bottomLeftHandle.x=topLeftHandle.x;
				leftHandle.x=topLeftHandle.x;
			}
			//If the Y position changed
			if(yToUse!=topLeftHandle.y)
			{
				yToUse=topLeftHandle.y;
				topHandle.y=topLeftHandle.y;
				topRightHandle.y=topLeftHandle.y;
			}
			//If the width changed update it and any handles that depend on it
			if(width!=bottomRightHandle.x-topLeftHandle.x)
			{
				width=bottomRightHandle.x-topLeftHandle.x;
				
				topHandle.x=topLeftHandle.x+width/2;
				topRightHandle.x=topLeftHandle.x+width;
				rightHandle.x=topLeftHandle.x+width;
				bottomRightHandle.x=topLeftHandle.x+width;
				bottomHandle.x=topLeftHandle.x+width/2;
				rotateHandle.x=topLeftHandle.x+width+20;
				if(isTransformPointLocked)
					transformPoint.x=width/2;
			}
			//If the height changed update it and any handles that depend on it
			if(height!=bottomRightHandle.y-topLeftHandle.y)
			{
				height=bottomRightHandle.y-topLeftHandle.y;
				rightHandle.y=topLeftHandle.y+height/2;
				bottomHandle.y=topLeftHandle.y+height;
				bottomLeftHandle.y=bottomRightHandle.y;
				leftHandle.y=topLeftHandle.y+height/2;
				rotateHandle.y=topLeftHandle.y+height/2;
				if(isTransformPointLocked)
					transformPoint.y=height/2;
			}
			
			if(selectedHandle==rotateHandle)
			{
				rotationToUse=Math.atan2(theModel.workspace.mouseY-(topLeftHandle.y+height/2),theModel.workspace.mouseX-topLeftHandle.x)*180/Math.PI;
			}
			
			var transMatrix:Matrix=new Matrix();
			transMatrix.tx-=transformPoint.x;
			transMatrix.ty-=transformPoint.y;
			transMatrix.rotate(rotationToUse*Math.PI/180);
			transMatrix.tx+=transformPoint.x;
			transMatrix.ty+=transformPoint.y;
			
			transform.matrix=transMatrix;
				
			(parent as UIComponent).invalidateDisplayList();
			invalidateDisplayList();
		}
	}
}